using System;
using System.Collections.Generic;
using System.Text;
using DeviceManager.Common;
using LoggingClient;

namespace DeviceManager.Device
{
    [Trace]
    public abstract class DeviceImpl : IDeviceImpl
    {
        public abstract bool OpenConnection();
        public abstract bool CloseConnection();
        public abstract bool SubscribeEvents();
        public abstract bool UnSubscribleEvents();
        public abstract bool Init();

        public event DeviceEvent ConnectionOpened = delegate { };
        public event DeviceEvent ConnectionClosed = delegate { };
        public event DeviceEvent DeviceError = delegate { };
        public event DeviceEvent StatusChanged = delegate { };
        public event DeviceEvent Timeout = delegate { };
        public event DeviceEvent Locked = delegate { };
        public event DeviceEvent Unlocked = delegate { };
        public event DeviceEvent LockTimeout = delegate { };
        public event DeviceEvent EnabledEventsDeferred = delegate { };

        // Events
        public virtual void OnConnectionOpened()
        {
            RaiseProtectedEvent(ConnectionOpened);

            EventUtils.RaiseEvents(StatusChanged, new object[] { this, "StDeviceStatus" });
        }

        public virtual void OnConnectionClosed()
        {
            RaiseProtectedEvent(ConnectionClosed);

            // Don't try to read device status when connection is closed as it can cause middleware exceptions.
            EventUtils.RaiseEvents(StatusChanged, new object[] { this, "StDeviceStatus", "NODEVICE" });
        }

        public virtual void OnDeviceError()
        {
            RaiseProtectedEvent(DeviceError);
        }

        public virtual void OnStatusChanged(string property, string status)
        {
            EventUtils.RaiseEvents(StatusChanged, new object[] { this, property, status });
        }

        public virtual void OnTimeout()
        {
            RaiseProtectedEvent(Timeout);
        }

        public virtual void OnLocked()
        {
            RaiseProtectedEvent(Locked);
        }

        public virtual void OnUnlocked()
        {
            RaiseProtectedEvent(Unlocked);
        }

        public virtual void OnLockTimeout()
        {
            RaiseProtectedEvent(LockTimeout);
        }

        public virtual void OnEnabledEventsDeferred()
        {
            RaiseProtectedEvent(EnabledEventsDeferred);
        }

        public virtual void RaiseProtectedEvent(MulticastDelegate customEvent)
        {
            EventUtils.RaiseEvents(customEvent, new object[] { this, string.Empty });
        }
    }
}
